package com.xxx.transaction;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;

/**
 * Rabbit MQ事务
 *  RabbitMQ有两种方式来解决事务问题：
		通过AMQP提供的事务机制实现；
		使用发送者确认模式实现；
	交互流程：
		mq客户端发送给服务器Tx.Select(开启事务模式)
		mq服务器端返回Tx.Select-Ok（开启事务模式ok）
		mq客户端推送消息
		mq客户端发送给事务提交Tx.Commit
		mq服务器端返回Tx.Commit-Ok
 * 	RabbitMQ的事务性能很差，与非事务相比，性能相差100倍以上。
 * 
 * @author guweiqiang
 * 2018年6月13日
 */
public class Producer {
	
	// 队列名称
	private static final String QUEUE_NAME = "rabbitMQ.transaction";
	
	// rabbit MQ server host
	private static final String HOST = "localhost";

	public static void main(String[] args) throws IOException, TimeoutException {
		// 1.创建连接工厂，并设置工厂相关属性
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(HOST); // MQ server
		
		// 2.创建一个连接
		Connection connection = factory.newConnection();
		
		// 3.创建一个通道
		Channel channel = connection.createChannel();
		
		// 4.声明一个队列
		channel.queueDeclare(QUEUE_NAME, true, false, false, null);
		// 第一个参数表示队列名称
		// 第二个参数为队列是否持久化（true表示是，队列将在服务器重启时生存）
		// 第三个参数为是否是独占队列（创建者可以使用的私有队列，断开后自动删除）
		// 第四个参数为当所有消费者客户端连接断开时是否自动删除队列
		// 第五个参数为队列的其他参数
		
		String message = "hello world！ now is："+new Date().getTime();
		System.out.println("send message：" + message);

		// 5.往队列里发送消息
		try {
		    channel.txSelect(); // 开启事务
		    // 发送消息
		    channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));
		    channel.txCommit(); // 提交事务
		} catch (Exception e) {
		    channel.txRollback(); // 回滚事务
		} finally {
			// 6.关闭连接
		    channel.close();
		    connection.close();
		}
	}

}
